using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace FrameWork.BehaviourTree
{
    

    /// <summary>
    /// 节点状态
    /// </summary>
    public enum NodeState
    {
        RUNNING,
        SUCCESS,
        FAILURE
    }

    /// <summary>
    /// 节点类
    /// 创建节点数据
    /// </summary>
    public class Node
    {
        // 节点状态
        protected NodeState state;

        // 公共父节点
        public Node parent;

        // 子节点
        protected List<Node> children = new List<Node>();

        // 字典，存放数据   名字+数据
        private Dictionary<string, object> dataContext = new Dictionary<string, object>();

        // 无参构造函数， 将父节点设置为空
        public Node()
        {
            parent = null;
        }

        // 有参构造函数，传入子节点
        public Node(List<Node> children)
        {
            foreach (Node child in children)
            {
                Attach(child);
            }
        }

        /// <summary>
        /// 添加节点
        /// </summary>
        /// <param name="node"></param>
        private void Attach(Node node)
        {
            node.parent = this;
            children.Add(node);
        }

        /// <summary>
        /// 添加子节点
        /// </summary>
        /// <param name="child"></param>
        public void AddChild(Node child)
        {
            Attach(child);
        }

        //
        public virtual NodeState Evaluate() => NodeState.FAILURE;

        //
        public void SetData(string key, object value)
        {
            dataContext[key] = value;
        }

        //
        public object GetData(string key)
        {
            object value = null;
            if (dataContext.TryGetValue(key, out value))
                return value;

            Node node = parent;
            while (node != null)
            {
                value = node.GetData(key);
                if (value != null)
                    return value;
                node = node.parent;
            }

            return null;
        }

        //
        public bool ClearData(string key)
        {
            if (dataContext.ContainsKey(key))
            {
                dataContext.Remove(key);
                return true;
            }


            Node node = parent;
            while (node != null)
            {
                bool cleared = node.ClearData(key);
                if (cleared)
                    return true;
                node = node.parent;
            }

            return false;
        }
    }

}